#https://www.bilibili.com/video/BV19541167cn?p=3&vd_source=c26a7d2aef5d2eddb9318602f0f58390
from abc import ABCMeta,abstractmethod
#抽象类，只定义了抽象方法（对外统一都叫pay),具体实现接口需要具体的类去实现
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        pass

#必须实现pay方法
class Alipei(Payment):
    def __init__(self,usehuabei=False):
        self.usehuabei=usehuabei

    def pay(self,money):
        if self.usehuabei:
            print("花呗支付%d元"%money)
        else:
            print("余额宝支付%d元"%money)

class WechatPay(Payment):
    def pay(self,money):
        print("微信支付%d元"%money)

#定义一个抽象类，里面要求实现create_payment这个抽象方法
class PaymentFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_payment(self):
        pass

class AlipeiFactory(PaymentFactory):
    #实现父类的抽象方法,返回一个Alipei对象
    def create_payment(self):
        return Alipei()

class HuabeiFactory(PaymentFactory):
    #实现父类的抽象方法,返回一个Alipei对象（其实是花呗）
    def create_payment(self):
        #此处进行逻辑封装，外界调用者根本不知道传了usehuabei=False
        return Alipei(usehuabei=True)

class WechatFactory(PaymentFactory):
    #实现父类的抽象方法,返回一个Wechat对象
    def create_payment(self):
        #此处进行逻辑封装，外界调用者根本不知道传了usehuabei=False
        return WechatPay()

if __name__ == '__main__':
    #想创建什么类型的支付，直接在这里调用不同的工厂即可，有了工厂就能生成对应的支付对象
    pf=WechatFactory()
    #创建一个alipay对象
    alipay=pf.create_payment()
    #使用创建出来的alipay对象来支付100元
    alipay.pay(100)